001 /**
002 * Created by IntelliJ IDEA.
003 * User: Wei Wang
004 * Date: Apr 16, 2003
005 * Time: 9:56:12 PM
006 */
007
008 package EVolve.util.phasedetectors;
009
010 import EVolve.util.equators.*;
011 import EVolve.util.settings.PhaseDetectorSetting;
012 import EVolve.util.phasedetectors.phasedetectorUI.PhaseDetectorToolBarState;
013 import EVolve.Scene;
014 import javax.swing.*;
015 import java.util.*;
016 import java.awt.*;
017
018 public class HotspotPhaseDetector extends PhaseDetector{
019 private UnorderedUnlimitedSet previous, current;
020 private final byte graduateChange = 0x0000, notChange = 0x0001;
021 private byte status[];
022 private int noiseTolerance, sampleSize, targetSize;
023 private float threshold;
024 private final String configName = "hotspot_detector";
025
026 private ArrayList samplePhase;
027 private UnorderedUnlimitedSet workingSet;
028
029 private JTextField[] contents;
030 private String[] tags;
031
032 public HotspotPhaseDetector() {
033 super();
034 workingSet = new UnorderedUnlimitedSet();
035 data.add(workingSet);
036
037 threshold = (float)0.8;
038 noiseTolerance = 2;
039 targetSize = sampleSize = 1;
040
041 samplePhase = new ArrayList();
042
043 tags = new String[4];
044 tags[0] = "[Noise tolerance (intervals)]";
045 tags[1] = "[Threshold]";
046 tags[2] = "[Sample]";
047 tags[3] = "[Target]";
048
049 JTextField textUpperThreshold, textNoiseTolerance;
050 JTextField textSampleSize, textTargetSize;
051 contents = new JTextField[4];
052 contents[0] = textNoiseTolerance = new JTextField();
053 contents[0].setColumns(2);
054
055 contents[1] = textUpperThreshold = new JTextField();
056 contents[1].setColumns(3);
057
058 contents[2] = textSampleSize = new JTextField();
059 contents[2].setColumns(2);
060
061 contents[3] = textTargetSize = new JTextField();
062 contents[3].setColumns(2);
063
064 textUpperThreshold.setText(String.valueOf(threshold));
065 textUpperThreshold.setToolTipText("Match threshold, from 0-1");
066 textSampleSize.setText(String.valueOf(sampleSize));
067 textSampleSize.setToolTipText("Take how many previous intervals as a sample set");
068 textTargetSize.setText(String.valueOf(targetSize));
069 textTargetSize.setToolTipText("Take how many intervals as a target set");
070 textNoiseTolerance.setText(String.valueOf(noiseTolerance));
071 textNoiseTolerance.setToolTipText("Noise tolerance");
072 refreshDetectorParameters();
073 }
074
075 public void reset() {
076 super.reset();
077 workingSet = new UnorderedUnlimitedSet();
078 data.add(workingSet);
079 samplePhase.clear();
080 }
081
082 public String getName() {
083 return "Hotspot Detector";
084 }
085
086 protected void refreshDetectorParameters() {
087 PhaseDetectorSetting setting = PhaseDetectorSetting.v();
088 setting.readDataFromFile(tags, contents, configName);
089 try {
090 noiseTolerance = Integer.parseInt(contents[0].getText());
091 threshold = Float.parseFloat(contents[1].getText());
092 sampleSize = Integer.parseInt(contents[2].getText());
093 targetSize = Integer.parseInt(contents[3].getText());
094 } catch (NumberFormatException e) {
095 Scene.showErrorMessage("Format of detector configuration file is incorrect.");
096 return;
097 }
098 }
099
100 protected void autoDetectPhase() {
101
102 refreshDetectorParameters();
103 phase.clear();
104 samplePhase.clear();
105
106 status = new byte[data.size()];
107
108 if ((sampleSize<=0) || (targetSize<=0)) return;
109
110 for (int i=0; i<data.size(); i++) {
111 if (i<sampleSize)
112 continue;
113
114 float rate = parse(i);
115
116 byte currentStatus = (rate >= threshold) ? notChange : graduateChange;
117 status[i] = currentStatus;
118 }
119 }
120
121 public Component[] createDetectorParamsControls() {
122 Component returnVal[] = new Component[8];
123
124 for (int i=0; i<tags.length; i++) {
125 String prompt = tags[i].substring(1,tags[i].length()-1) + ": ";
126 returnVal[i*2] = new JLabel(prompt);
127 returnVal[i*2+1] = contents[i];
128 contents[i].setPreferredSize(new java.awt.Dimension(20,26));
129 }
130
131 return returnVal;
132 }
133
134 public void collectData(long xMappedId, long yMappedId) {
135 int x = (int)(xMappedId/interval);
136
137 if (x >= data.size()) {
138 workingSet = new UnorderedUnlimitedSet();
139 data.add(workingSet);
140 }
141
142 workingSet.addElement(yMappedId);
143 }
144
145 public void saveSetting() {
146 PhaseDetectorSetting.v().save(tags,contents,configName);
147 }
148
149 public void triggerPhases(int noiseTolerance) {
150 PhaseEntityTrigger trigger = new PhaseEntityTrigger();
151 ArrayList triggered = trigger.gatherTiggeredPhase(data, noiseTolerance);
152
153 if (triggered.size() == 0) {
154 Scene.showErrorMessage("No phase triggered.");
155 } else
156 undoList.add(triggered);
157 }
158
159 private float parse(int checkPoint) {
160
161 float match = 0, average = targetSize;
162
163 for (int i=checkPoint; i<checkPoint+targetSize; i++) {
164 float rate = 0, factor = 1;
165 if (i >= data.size()) {
166 average = i-checkPoint+1;
167 break;
168 }
169 current = (UnorderedUnlimitedSet)data.get(i);
170 for (int j=checkPoint-1; j>=checkPoint-sampleSize; j--) {
171 if (j != checkPoint-1) factor = factor / 2;
172 previous = (UnorderedUnlimitedSet)data.get(j);
173 rate = rate + ((float)previous.intersection(current).size()/(float)previous.union(current).size())*factor;
174 }
175 match = match + rate;
176 }
177
178 return match/average;
179 }
180
181 protected void generatePhases() {
182 phase.clear();
183 // generate phases detected automatically.
184 autoDetectPhase();
185 int previous = status[0], noise = 0;
186 for (int i=1; i<status.length; i++) {
187 if (status[i] != previous) {
188 noise ++;
189 if (noise > noiseTolerance) {
190 if (previous == graduateChange)
191 phase.add(new Integer(i-noise));
192 else
193 phase.add(new Integer(i-noise+1));
194 noise = 0;
195 previous = status[i];
196 }
197 } else {
198 noise = 0;
199 }
200 }
201
202 /*for (int i=0; i<samplePhase.size(); i++) {
203 phase.add(samplePhase.get(i));
204 }*/
205
206 ArrayList tobeDel = new ArrayList();
207 for (int i=0; i<undoList.size(); i++) {
208 Object value = undoList.get(i);
209 if (value instanceof ArrayList) {
210 for (int j=0; j<((ArrayList)value).size(); j++)
211 phase.add(((ArrayList)value).get(j));
212 } else {
213 int aPhase = ((Integer)value).intValue();
214 if (aPhase < 0) {// a removed phase
215 for (int j=0; j<phase.size(); j++) {
216 if (((Integer)phase.get(j)).intValue() == (-1*aPhase)) {
217 tobeDel.add(new Integer(j));
218 }
219 }
220 } else
221 phase.add(value);
222 }
223 }
224
225 int counter = 0;
226 for (int i=0; i<tobeDel.size(); i++) {
227 phase.remove(((Integer)tobeDel.get(i)).intValue()-counter);
228 counter ++;
229 }
230 }
231
232 protected void initialToolbarState() {
233 toolbarState = new PhaseDetectorToolBarState();
234 toolbarState.selectedOption = 0;
235 toolbarState.optionsControlState = new HashMap();
236 }
237 }